package com.zmn.plat.business.interfaces.sendtemplate;

import java.util.Objects;

import com.zmn.manager.redis.lock.DistributedLock;
import com.zmn.manager.redis.lock.DistributedLockUtils;
import com.zmn.plat.business.impl.sendtemplate.*;
import com.zmn.plat.manager.exception.ZmnErrorMessageException;
import com.zmn.plat.model.entity.message.MsgTemplate;
import com.zmn.plat.model.entity.push.ZmnSms;

/**
 * 描述：zmn 消息发送接口类 想要拓展发送消息类型，只需要实现该接口，并且在该接口内部提供一个静态的方法进行调用
 *
 * @author wangjie
 * @since 2020/6/19 10:51
 **/
@FunctionalInterface
public interface SendSmsInfoBService {

    /**
     * 描述：redis 锁key
     *
     * @author wangjie
     * @since 2020/6/19 14:34
     **/
    String REDIS_LOCK_KEY = "plat:lock:repeat:sendsms";

    /**
     * 描述：锁有效时间（秒）
     *
     * @author wangjie
     * @since 2020/6/19 14:34
     **/
    int LOCK_TIME_OUT = 10;

    /**
     * 描述：发送消息
     *
     * @param msgTemplate
     *            消息模板
     * @param zmnSms
     *            消息内容
     * @return java.lang.Integer 发送状态 code 码
     * @author wangjie
     * @since 2020/6/19 11:36
     **/
    Integer doSend(MsgTemplate msgTemplate, ZmnSms zmnSms) throws IllegalAccessException;

    /**
     * 描述：使用微信发送消息
     *
     * @return com.zmn.plat.business.interfaces.sendtemplate.ZmnSendSmsInfoBService
     * @author wangjie
     * @since 2020/6/19 10:50
     **/
    static SendSmsInfoBService byWeChat() {

        return ((msgTemplate, zmnSms) -> {

            if (Objects.isNull(msgTemplate) || Objects.isNull(zmnSms)) {
                throw new IllegalAccessException("参数不能为null");
            }
            String redisKey = REDIS_LOCK_KEY + ":wechat:" + zmnSms.getOpenId() + msgTemplate.getTemplateId();
            DistributedLock lock = DistributedLockUtils.build(redisKey, LOCK_TIME_OUT);
            if (lock.tryLock()) {
                try {
                    return WeChatSendSmsInfoBServiceImpl.getSingleton().doSend(msgTemplate, zmnSms);
                } catch (Exception e) {
                    throw new ZmnErrorMessageException(e.getMessage());
                } finally {
                    lock.unlock();
                }
            } else {
                throw new ZmnErrorMessageException("获取锁失败！");
            }
        });
    }

    /**
     * 描述：使用创蓝短信发送
     *
     * @return com.zmn.plat.business.interfaces.sendtemplate.ZmnSendSmsInfoBService
     * @author wangjie
     * @since 2020/6/19 10:50
     **/
    static SendSmsInfoBService byCl() {

        return ((msgTemplate, zmnSms) -> {

            if (Objects.isNull(msgTemplate) || Objects.isNull(zmnSms)) {
                throw new IllegalAccessException("参数不能为null");
            }
            String redisKey = REDIS_LOCK_KEY + ":cl:" + zmnSms.getMobile() + msgTemplate.getTemplateId();
            DistributedLock lock = DistributedLockUtils.build(redisKey, LOCK_TIME_OUT);
            if (lock.tryLock()) {
                try {
                    return CLSendSmsInfoBServiceImpl.getSingleton().doSend(msgTemplate, zmnSms);
                } catch (Exception e) {
                    throw new ZmnErrorMessageException(e.getMessage());
                } finally {
                    lock.unlock();
                }
            } else {
                throw new ZmnErrorMessageException("获取锁失败！");
            }
        });
    }

    /**
     * 描述：使用阿里短信发送
     *
     * @return com.zmn.plat.business.interfaces.sendtemplate.ZmnSendSmsInfoBService
     * @author wangjie
     * @since 2020/6/19 10:50
     **/
    static SendSmsInfoBService byAli() {

        return ((msgTemplate, zmnSms) -> {

            if (Objects.isNull(msgTemplate) || Objects.isNull(zmnSms)) {
                throw new IllegalAccessException("参数不能为null");
            }
            String redisKey = REDIS_LOCK_KEY + ":ali:" + zmnSms.getMobile() + msgTemplate.getTemplateId();
            DistributedLock lock = DistributedLockUtils.build(redisKey, LOCK_TIME_OUT);
            if (lock.tryLock()) {
                try {
                    return AliSendSmsInfoBServiceImpl.getSingleton().doSend(msgTemplate, zmnSms);
                } catch (Exception e) {
                    throw new ZmnErrorMessageException(e.getMessage());
                } finally {
                    lock.unlock();
                }
            } else {
                throw new ZmnErrorMessageException("获取锁失败！");
            }
        });
    }

    /**
     * 描述：使用掌上通发送
     *
     * @return com.zmn.plat.business.interfaces.sendtemplate.ZmnSendSmsInfoBService
     * @author wangjie
     * @since 2020/6/19 10:51
     **/
    static SendSmsInfoBService byZst() {

        return ((msgTemplate, zmnSms) -> {

            if (Objects.isNull(msgTemplate) || Objects.isNull(zmnSms)) {
                throw new IllegalAccessException("参数不能为null");
            }
            String redisKey = REDIS_LOCK_KEY + ":zst:" + zmnSms.getMobile() + msgTemplate.getTemplateId();
            DistributedLock lock = DistributedLockUtils.build(redisKey, LOCK_TIME_OUT);
            if (lock.tryLock()) {
                try {
                    return ZSTSendSmsInfoBServiceImpl.getSingleton().doSend(msgTemplate, zmnSms);
                } catch (Exception e) {
                    throw new ZmnErrorMessageException(e.getMessage());
                } finally {
                    lock.unlock();
                }
            } else {
                throw new ZmnErrorMessageException("获取锁失败！");
            }
        });
    }

    /**
     * 描述：使用掌上通发送
     *
     * @return com.zmn.plat.business.interfaces.sendtemplate.ZmnSendSmsInfoBService
     * @author wangjie
     * @since 2020/6/19 10:51
     **/
    static SendSmsInfoBService byBaiDu() {

        return ((msgTemplate, zmnSms) -> {
            if (Objects.isNull(msgTemplate) || Objects.isNull(zmnSms)) {
                throw new IllegalAccessException("参数不能为null");
            }
            try {
                return BaiduSendSmsInfoBServiceImpl.getSingleton().doSend(msgTemplate, zmnSms);
            } catch (Exception e) {
                throw new ZmnErrorMessageException(e.getMessage());
            }
        });
    }
}
